package cn.wen.mybatis.framework.scripting.defaults;


import cn.wen.mybatis.framework.builder.SqlSourceBuilder;
import cn.wen.mybatis.framework.mapping.BoundSql;
import cn.wen.mybatis.framework.mapping.SqlSource;
import cn.wen.mybatis.framework.scripting.xmltags.DynamicContext;
import cn.wen.mybatis.framework.scripting.xmltags.SqlNode;
import cn.wen.mybatis.framework.session.Configuration;

import java.util.HashMap;


/**
 * 而RawSqlSource解析含有#{}的sql语句
 * select * from Blog where id = #{id}
 * 如果当前的sql语句不是动态sql，也就是说sql语句中不包含${}占位符的话，
 * RawSqlSource会将当前sql中的#{}占位符替换为?，并维护其参数映射关系，最终返回一个StaticSqlSource对象。
 */
public class RawSqlSource implements SqlSource {

	private final SqlSource sqlSource;

	public RawSqlSource(Configuration configuration, SqlNode rootSqlNode, Class<?> parameterType) {
		this(configuration, getSql(configuration, rootSqlNode), parameterType);
	}

	public RawSqlSource(Configuration configuration, String sql, Class<?> parameterType) {
		// 创建一个SqlSourceBuilder实例，也是建造者
		SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
		// 获取形参的类型
		Class<?> clazz = parameterType == null ? Object.class : parameterType;
		// 执行解析，也就是将sql语句中的#{}占位符替换成?
		sqlSource = sqlSourceParser.parse(sql, clazz, new HashMap<>());
	}
	//从根节点开始处理所有的SqlNode
	private static String getSql(Configuration configuration, SqlNode rootSqlNode) {
		DynamicContext context = new DynamicContext(configuration, null);
		rootSqlNode.apply(context);
		return context.getSql();
	}

	@Override
	public BoundSql getBoundSql(Object parameterObject) {
		return sqlSource.getBoundSql(parameterObject);
	}

}
